/**
 * 
 */
package ca.csf.dfc.poo.environnement;

import java.util.Random;

import ca.csf.dfc.poo.exceptions.IllegalPositionXException;
import ca.csf.dfc.poo.exceptions.IllegalPositionYException;
import ca.csf.dfc.poo.exceptions.IllegalRecompenseException;
import ca.csf.dfc.poo.exceptions.IllegalTableauDecisionException;
import ca.csf.dfc.poo.exceptions.InvalidDirectionException;

/**
 * @author �quipe 1
 *
 */
public class RobotLineaire extends Robot{

	/**
	 * Direction courante dans laquelle le robot est.
	 */
	private int m_Direction;

	/**
	 * Constructeur par initialisation recevant la position en x et y du robot.
	 * @param p_X : Position sur l'axe des abscisses.
	 * @param p_Y : Position sur l'axe des ordonn�es.
	 * @throws IllegalRecompenseException 
	 * @throws IllegalPositionYException 
	 * @throws IllegalPositionXException 
	 * @throws InvalidDirectionException 
	 */
	public RobotLineaire(int p_X, int p_Y) throws IllegalPositionXException, IllegalPositionYException, IllegalRecompenseException, InvalidDirectionException {
		super(p_X, p_Y);
		this.setDirection(RobotLineaire.AUCUNE);
	}
	
	/**
	 * On r�cup�re la direction dans laquelle le robot se d�place.
	 * @return the m_Direction
	 */
	public int getDirection() {
		return m_Direction;
	}

	/**
	 * Permet de changer la direction dans laquelle le robot se d�place.
	 * @param Direction dans lequel le robot va se d�placer.
	 * @throws InvalidDirectionException 
	 */
	protected void setDirection(int p_Direction) throws InvalidDirectionException {
	    //On regarde si on veut mettre une direction invalide.
	    if ((p_Direction < -1) || (p_Direction > 3))
	        throw new InvalidDirectionException();
	    
		this.m_Direction = p_Direction;
	}

	/**
	 *  On continue dans la m�me direction tant qu'on ne rencontre pas un mur,un obstacle,
	 *  ou un interdit ensuite on prend une autre direction au hasard et le cycle recommence.
	 * @throws IllegalTableauDecisionException 
	 * @throws InvalidDirectionException 
	 * @see ca.csf.dfc.poo.environnement.Robot#prendreDecision(ca.csf.dfc.poo.environnement.Case, ca.csf.dfc.poo.environnement.Case, ca.csf.dfc.poo.environnement.Case, ca.csf.dfc.poo.environnement.Case)
	 */
	@Override
	public int prendreDecision(Case[] p_TabCases) throws IllegalTableauDecisionException, InvalidDirectionException
	{
	  //On regarde si le tableau ne contient pas 4 cases.
        if (p_TabCases.length != 4)
            throw new IllegalTableauDecisionException();
        
	    int direction = AUCUNE;
	    
		//Si on a aucune direction pr�sentement ou qu'on ne peut pas se déplacer
	    // dans la direction courante, on en trouve une.
		if ((this.getDirection() == RobotLineaire.AUCUNE) || (p_TabCases[this.getDirection()] == null))
		{
			direction = trouverDirection(p_TabCases);
			
			if (direction != RobotLineaire.AUCUNE)
			{
				this.setDirection(direction);
			}
		}
		else
		{
			//On peut continuer dans la même direction qu'on était.
		    direction = this.getDirection();
		}
		
		return direction;
	}
	
	/**
	 * Permet au robot de trouver une direction valide au hasard.
	 * @param p_Haut : Case au dessus du robot.
	 * @param p_Droit : Case � droite du robot.
	 * @param p_Bas : Case en dessous du robot.
	 * @param p_Gauche : Case � gauche du robot.
	 * @return La direction choisie.
	 * @throws IllegalTableauDecisionException 
	 */
	private int trouverDirection(Case[] p_TabCases) throws IllegalTableauDecisionException
	{
	  //On regarde si le tableau ne contient pas 4 cases.
        if (p_TabCases.length != 4)
            throw new IllegalTableauDecisionException();
        
	    Random r = new Random();
		int direction = RobotLineaire.AUCUNE;
		int temp = 0;
		
		//On v�rifie si on a au moins un chemin de sortie
		if ((p_TabCases[HAUT] != null) || (p_TabCases[DROITE] != null) || 
			(p_TabCases[BAS] != null) || (p_TabCases[GAUCHE] != null))
		{
			boolean valide = false;
			
			do
			{
				temp = r.nextInt(4);
				
				if (p_TabCases[temp] != null)
				{
					direction = temp;
					valide = true;
				}
			} 
			while(!valide);
			
		}
		
		return direction;
	}
}
